 import { useContext, useEffect, useMemo, useCallback, useState, useRef } from 'react';
import { Tooltip } from 'antd';
import RetryIcon from '../icon/RetryIcon';
import SuccessIcon from '../icon/SuccessIcon';
import CancelButton from './actions/CancelButton';
import DeleteButton from './actions/DeleteButton';
import FileName from './FileName';
import PauseResumeButton from './actions/PauseResumeButton';
import ProgressBar from './ProgressBar';
import WaitButton from './actions/WaitButton';
import { getFileTypeIconSvg, InbizIcon } from '@inbiz/utils';
import { getMessage } from '@inbiz/react';
import { GlobalRegistry } from '@inbiz/core';
import { formatSizeAndUnits, getImgToBase64, splitFileName } from '../../utils/tool';
import { InBizUploadCtx, InBizUploadListCtx } from '../../context';
import { imgType } from '../../utils/shared';
import CancelThumbIcon from '../icon/CancelThumbIcon';

interface IProps {
  id: number;
  status: string;
  error: { tip?: string };
  strategy?: string;
  filename: string;
  name: string;
  regionUrl?: string;
  fromServer?: boolean;
  fileid: string | number;
  folderId: string | number;
  filelastsize: string | number;
  folderPath: string;
  deleteEnabled: boolean;
  chunkingEnabled: boolean;
  viewMode?: string;
  file?: {strategy?:string}
}

const ListItem = (props: IProps) => {
  const {
    id,
    status,
    error,
    strategy,
    filename,
    name,
    fromServer = false,
    fileid,
    filelastsize,
    folderPath,
    viewMode,
    file
  } = props;
  const { thumbnail, fixedHeight, readOnly, uploader, statusEnum, showFolderPath = true, showListFloatLayer, onItemClick } =
    useContext(InBizUploadCtx);
  const { onClickFileItem, showRenameModal } = useContext(InBizUploadListCtx);
  const chunkingEnabled = uploader.options.chunking && uploader.options.chunking.enabled;
  const { ext } = splitFileName(filename || name);
  const statusRef = useRef(status);
  const [showModal, setShowModal] = useState(false);
  const [base64, setBase64] = useState<string | null>(null);

  /**
   * 
   * @param id 文件id
   * @param status 文件状态
   * @returns 根据文件状态返回对应的提示语
   */
  const getUploadStatus = useCallback((id: string | number, status: string) => {
    const file = uploader.methods.getFile(id);
    if (file?.size == 0) return getMessage('inbizUpload.nullContent');
    switch (status) {
      case statusEnum.QUEUED:
        return getMessage('inbizUpload.queued');
      case statusEnum.UPLOADING:
        return file?.progre?.speed;
      case statusEnum.PAUSED:
        return getMessage('inbizUpload.paused');
      case statusEnum.UPLOAD_SUCCESSFUL:
        return getMessage('inbizUpload.uploadSuccess');
      case statusEnum.DELETING:
        return getMessage('inbizUpload.uploadSuccess');
      case statusEnum.UPLOAD_FAILED:
        if (error?.tip) {
          return getMessage(error.tip);
        }
        return file?.strategy == 'skip' ? getMessage('inbizUpload.skiped') : getMessage('inbizUpload.uploadError');
      case statusEnum.UPLOAD_EXISNAME:
        return getMessage('inbizUpload.exisname');
      default:
        return getMessage('inbizUpload.queued');
    }
  }, [error]);

  /**
   * 
   * @param id 文件id
   * @returns 判断文件策略是否为跳过
   */
  const isWarn = (id: string | number) => {
    const file = uploader.methods.getFile(id);
    return file?.strategy === 'skip' ? true : false;
  };

  /**
   * 
   * @param id 文件id
   * @param status 文件状态
   * @returns 根据文件策略返回对应的提示语
   */
  const getThumbWarn = (id: string | number, status: string) => {
    return '';
  };

  // 过滤文件状态
  const filterStatus = useMemo(() => {
    if (statusRef.current === status) {
      return '1';
    }
    statusRef.current = status;
    if (status === statusEnum.SUBMITTED || status === statusEnum.QUEUED) {
      return '1';
    }

    return status;
  }, [status]);

  // 渲染文件显示图标
  const renderFileIcon = () => {
    return (
      <>
        <div className='react-fine-uploader-gallery-img-container'>
          <div className='react-fine-uploader-gallery-file-img'>
            {thumbnail ? (
              <img
                src={`/Thumbnails/default/${fileid}.${ext}`}
                style={{ backgroundSize: 'contain' }}
                onError={(e) =>
                  (e.target.src = getFileTypeIconSvg(uploader.methods.getName(id) || filename))
                }
                className='react-fine-uploader-gallery-file-thumb'
              />
            ) : (
              <img
                className={base64 ? 'react-fine-uploader-gallery-file-type-img' : 'react-fine-uploader-gallery-icon'}
                src={base64 ? base64 : getFileTypeIconSvg(uploader.methods.getName(id) || filename)}
                alt={base64 ? base64 : getFileTypeIconSvg(uploader.methods.getName(id) || filename)}
                style={onItemClick && !!fileid ? { cursor: 'pointer' } : {}}
                onClick={() => {
                  if (!fileid) {
                    return;
                  }
                  onClickFileItem(fileid, status);
                }}
              />
            )}
          </div>
        </div>
        {thumbnail ? (
          <div
            className={thumbnail ? 'react-fine-uploader-gallery-content-mask--hover' : ''}
            style={
              status !== 'uploading'
                ? {
                  height: '88px',
                  cursor: onItemClick ? 'pointer' : 'default',
                }
                : {}
            }
            onClick={() => onClickFileItem(fileid, status)}
          />
        ) : null}
      </>
    );
  };

  // 渲染文件显示信息
  const renderFileInfo = () => {
    let size: number = 0;
    if (fromServer) {
      size = Number(filelastsize);
    } else {
      size = uploader.methods.getSize(id) >= 0 ? uploader.methods.getSize(id) : Number(filelastsize);
    }
    const uploadStatus = getUploadStatus(id, status);
    return (
      <div className='react-fine-uploader-gallery-file-info'>
        <div className='react-fine-uploader-gallery-file-footer'>
          <FileName
            className='react-fine-uploader-gallery-filename'
            id={id}
            filename={filename || name}
            hasClick={onItemClick ? true : false}
            fileClick={() => onClickFileItem(fileid, status)}
            viewMode={viewMode}
          />
        </div>
        {!thumbnail ? (
          <div className='react-fine-uploader-gallery-progress-text-list'>
            <span className='react-fine-uploader-gallery-progress-file-size'>
              {`${formatSizeAndUnits(size)}`}
            </span>
            {
              viewMode != 'look' && <span className='react-fine-uploader-gallery-progress-status' title={uploadStatus}>
                {status === statusEnum.UPLOAD_FAILED && <CancelThumbIcon />}
                {uploadStatus}
              </span>
            }
          </div>
        ) : null}
      </div>
    );
  };

  // 根据文件上传状态，渲染上传至某个文件夹
  const renderFolderPath = () => {
    return (
      <span
        className='react-fine-uploader-gallery-progress-folder-path'
        title={folderPath}
        style={status === statusEnum.UPLOAD_SUCCESSFUL ? { color: 'var(--inbiz-color-primary)', cursor: 'pointer' } : undefined}
      >
        {folderPath}
      </span>
    )
  }

  // 根据上传状态渲染删除按钮，或者是退出按钮
  const renderDelCanBtn = useMemo(() => {
    if (readOnly) {
      return null;
    }
    // 浮层列表上传成功的文件不需要显示删除图标
    if (status === statusEnum.UPLOAD_SUCCESSFUL && showListFloatLayer) {
      return null;
    }
    return status === statusEnum.UPLOAD_SUCCESSFUL ? (
      <DeleteButton
        className='react-fine-uploader-gallery-delete-button'
        id={id}
        currentFile={{
          id,
          filename: filename || name,
          fileid,
          filelastsize,
          fromServer,
        }}
      />
    ) : (
      <CancelButton className='react-fine-uploader-gallery-cancel-button' id={id} />
    );
  }, [readOnly, showListFloatLayer, filterStatus]);

  // 渲染按钮
  const renderLiBtn = () => {
    return (
      viewMode != 'look' && <div className='react-fine-uploader-gallery-file-btn-container'>
        {thumbnail && (
          <>
            <div
              style={{ display: isWarn(id) ? 'block' : 'none' }}
              className='react-fine-uploader-gallery-thumbnail-warn'
            >
              <Tooltip title={getThumbWarn(id, status)} placement='bottom'>
                <InbizIcon
                  type='icon-shangchuanchucuo'
                  style={{ fontSize: '16px', color: '#fba147' }}
                />
              </Tooltip>
            </div>
            {status === statusEnum.UPLOAD_SUCCESSFUL && (
              <div className='react-fine-uploader-gallery-thumbnail-success'>
                <Tooltip title={getThumbWarn(id, status)} placement='bottom'>
                  <InbizIcon type='icon-yiwancheng' style={{ fontSize: '16px' }} />
                </Tooltip>
              </div>
            )}
            {status === statusEnum.UPLOAD_FAILED && !strategy && (
              <div className='react-fine-uploader-gallery-thumbnail-failed'>
                <Tooltip title={getMessage(error?.tip)} placement='bottom'>
                  <InbizIcon
                    type='icon-shangchuanchucuo'
                    style={{ fontSize: '16px', color: '#ec705f' }}
                  />
                </Tooltip>
              </div>
            )}
          </>
        )}
        {renderDelCanBtn}
        <WaitButton id={id} status={status} />
        {chunkingEnabled && (status === statusEnum.UPLOADING || status === statusEnum.PAUSED) && (
          <PauseResumeButton className='react-fine-uploader-gallery-pause-resume-button' id={id} />
        )}
        {status === statusEnum.UPLOAD_SUCCESSFUL && !thumbnail ? (
          <div className='react-fine-uploader-gallery-success-button'>
            <SuccessIcon />
          </div>
        ) : null}
        {status === statusEnum.UPLOAD_EXISNAME && !thumbnail ? (
          <div className='react-fine-uploader-gallery-exisname-button' onClick={() => setShowModal(true)}>
            <RetryIcon />
          </div>
        ) : null}
        {status === statusEnum.UPLOAD_FAILED && !thumbnail ? (
          strategy === 'skip' ? (
            <Tooltip title={getMessage(error?.tip)} placement='bottom'>
              <div className='react-fine-uploader-gallery-failed-button'>
                <InbizIcon
                  type='icon-shangchuanchucuo'
                  style={{ fontSize: '16px', color: '#fba147' }}
                />
              </div>
            </Tooltip>
          ) : (
            file?.strategy !== 'skip' && <div
              className='react-fine-uploader-gallery-exisname-button'
              onClick={() => {
                uploader.methods.retry(id);
              }}
            >
              <RetryIcon />
            </div>
          )
        ) : null}
      </div>
    );
  };

  // 渲染文件详情
  const renderContent = useMemo(() => {
    return (
      <li
        key={id}
        style={{ margin: (thumbnail && fixedHeight) ? '8px 15px 20px 0' : viewMode == 'look' ? thumbnail ? '0 28px 28px 0' : '0 0 6px 0' : '', border: viewMode == 'look' ? 'none' : '' }}
        className='react-fine-uploader-gallery-file'
      >
        <ProgressBar className='react-fine-uploader-gallery-progress-bar' id={id} />
        {
          showListFloatLayer ? (
            <>
              <div className='react-fine-uploader-gallery-li-left'>
                {renderFileIcon()}
                {renderFileInfo()}
              </div>
              <div
                style={!showFolderPath ? { flex: 'unset', marginLeft: '10px' } : undefined}
                className='react-fine-uploader-gallery-li-right'
              >
                {showListFloatLayer && showFolderPath && renderFolderPath()}
                {renderLiBtn()}
              </div>
            </>
          ) : (
            <>
              {renderFileIcon()}
              {renderFileInfo()}
              {renderLiBtn()}
            </>
          )
        }
      </li>
    );
  }, [viewMode, filterStatus, filelastsize, base64, readOnly, error, showModal, GlobalRegistry.getDesignerLanguage()]);

  // 生成图片的base64
  useEffect(() => {
    if (imgType.includes(ext)) {
      const _file: any = uploader.methods.getFile(id);
      getImgToBase64(_file).then(res => {
        if (res) {
          setBase64(res);
        }
      });
    }
  }, [id])

  return (
    <>
      {renderContent}
      {showModal && showRenameModal(id, () => {
        setShowModal(false)
      })}
    </>
  );
};

export default ListItem;
